package com.efrei.schoolmanager.views;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.List;

import javax.swing.GroupLayout;
import javax.swing.GroupLayout.Alignment;
import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

import com.efrei.schoolmanager.controlers.ControleurClasse;
import com.efrei.schoolmanager.exceptions.LogicException;
import com.efrei.schoolmanager.model.obj.Niveau;
import com.efrei.schoolmanager.tools.Tools;
import com.efrei.schoolmanager.views.components.CustomButton;
import com.efrei.schoolmanager.views.components.CustomTextField;

/**
 * JDialog pour l'ajout d'une classe
 * 
 */
public class DialogAjouterClasse extends JDialog {
	private static final long serialVersionUID = 6682980176462906340L;

	private final static String TITLE = "Ajouter une classe";

	// Proprietaire de cette dialog(objectif: rendre modale la jdialog)
	private final JFrame proprio;

	// JPanels
	private JPanel titlePanel, formulairePanel, butonPanel;

	// JLabels
	private JLabel titleLabel, nomClasseLabel, promotionClasseLabel,
			niveauClasseLabel;

	// CustomTextField
	private CustomTextField nomClasseTextField, promotionClasseTextField;

	// JComboBox
	private JComboBox niveauClasseComboBox;

	// CustomButton
	private CustomButton ajouterClasseButton;

	// Controleur de la classe
	private final ControleurClasse controleur;

	// Pour fermer la jdialog
	private final DialogAjouterClasse dialog;

	public DialogAjouterClasse(JFrame frame, ControleurClasse controleur) {
		super(frame, TITLE, true);
		dialog = this;
		this.controleur = controleur;
		proprio = frame;
		initLabels();
		initPanels();
		initTextFields();
		initComboBox();
		initButtons();
		remplirTitlePanel();
		remplirFormulairePanel();
		remplirButonPanel();
		configurerVue();
	}

	private void remplirButonPanel() {
		butonPanel = new JPanel(new FlowLayout());
		butonPanel.add(ajouterClasseButton);
	}

	private void remplirFormulairePanel() {
		// Gestionnaire de positionnement
		GroupLayout layout = new GroupLayout(formulairePanel);
		formulairePanel.setLayout(layout);
		// Espacement des composants
		layout.setAutoCreateGaps(true);
		// Espacement entre composants et conteneur
		layout.setAutoCreateContainerGaps(true);

		// Groupe sequentiel sur l'axe horizontal
		GroupLayout.SequentialGroup hGroup = layout.createSequentialGroup();

		/* Constitution des groupes paralleles horizontalement */
		// 1e colonne
		hGroup.addGroup(layout.createParallelGroup()
				.addComponent(nomClasseLabel)
				.addComponent(promotionClasseLabel)
				.addComponent(niveauClasseLabel));
		// 2e colonne
		hGroup.addGroup(layout.createParallelGroup()
				.addComponent(nomClasseTextField)
				.addComponent(promotionClasseTextField)
				.addComponent(niveauClasseComboBox));
		layout.setHorizontalGroup(hGroup);

		/* Constitution des groupes paralleles verticalement */
		GroupLayout.SequentialGroup vGroup = layout.createSequentialGroup();
		// 1e ligne
		vGroup.addGroup(layout.createParallelGroup(Alignment.BASELINE)
				.addComponent(nomClasseLabel).addComponent(nomClasseTextField));
		// 2e ligne
		vGroup.addGroup(layout.createParallelGroup(Alignment.BASELINE)
				.addComponent(promotionClasseLabel)
				.addComponent(promotionClasseTextField));
		// 3e ligne
		vGroup.addGroup(layout.createParallelGroup(Alignment.BASELINE)
				.addComponent(niveauClasseLabel)
				.addComponent(niveauClasseComboBox));
		layout.setVerticalGroup(vGroup);
	}

	private void remplirTitlePanel() {
		titlePanel.add(titleLabel);
	}

	/**
	 * Configurer les options de la vue
	 */
	private void configurerVue() {
		setLayout(new BorderLayout());
		this.add(titlePanel, BorderLayout.NORTH);
		this.add(formulairePanel, BorderLayout.CENTER);
		this.add(butonPanel, BorderLayout.SOUTH);
		Dimension preferedSize = getPreferredSize();
		Dimension dimensionIdeale = new Dimension(preferedSize.width + 80,
				preferedSize.height + 35);
		setMinimumSize(dimensionIdeale);
		setSize(dimensionIdeale);
		this.setLocationRelativeTo(proprio);

	}

	private void initButtons() {
		ajouterClasseButton = new CustomButton("Ajouter la classe");
		ajouterClasseButton
				.addActionListener(new ajouterClasseFinishActionListener());
	}

	private void initComboBox() {
		niveauClasseComboBox = new JComboBox();
		List<Niveau> niveauList = controleur.getNiveaux();
		for (Niveau niveau : niveauList) {
			niveauClasseComboBox.addItem(niveau);
		}
	}

	private void initTextFields() {
		nomClasseTextField = new CustomTextField();
		promotionClasseTextField = new CustomTextField();

	}

	private void initPanels() {
		titlePanel = new JPanel(new FlowLayout());
		formulairePanel = new JPanel();
		butonPanel = new JPanel(new FlowLayout());
	}

	private void initLabels() {
		titleLabel = new JLabel(TITLE);
		nomClasseLabel = new JLabel("Nom : ");
		promotionClasseLabel = new JLabel("Promotion : ");
		niveauClasseLabel = new JLabel("Niveau");
	}

	public boolean showDialog() {
		setVisible(true);
		return true;
	}

	/**
	 * Listener : lorsque l'utilisateur valide l'ajout de la classe, la fenetre
	 * se ferme, et renvoie à la classe appelante la classe nouvellement ajoutee
	 * 
	 */
	class ajouterClasseFinishActionListener implements ActionListener {

		@Override
		public void actionPerformed(ActionEvent arg0) {
			String error = null;

			String nom = null;
			String promotionText = null;
			int promotion;
			try {
				// Verifier le nom
				nom = nomClasseTextField.getText();
				if (nom == null || nom.equals(""))
					throw new LogicException("Nom vide");
				// Verifier la promotion
				promotionText = promotionClasseTextField.getText();
				if (promotionText == null || promotionText.equals(""))
					throw new LogicException("Promotion vide");
				// Parser le champ pour optenir un entier
				promotion = Integer.parseInt(promotionText);
				if (promotion < 1)
					throw new LogicException("Promotion < 1");

				// Ajout de la classe
				controleur.addClasse(nom, promotion,
						(Niveau) niveauClasseComboBox.getSelectedItem());
			} catch (NumberFormatException e) {
				System.err.println(e);
				error = "Nombre attendu";
			} catch (LogicException e) {
				System.err.println(e);
				error = e.getMessage();
			}
			if (error != null) {
				Tools.displayError(error, "Erreur");
			} else {
				dialog.setVisible(false);
			}
		}
	}

}
